五条原型规则

  1. 所有的引用类型(对象,数组,函数),都具有对象特性,即可自由扩展属性(除了null以外)。
  2. 所有的引用类型(对象,数组,函数),都有一个__proto__属性,属性值都是一个普通对象。
  3. 所有的函数都有一个prototype属性,属性值是一个普通对象。
  4. 所有的引用类型(对象,数组,函数),__proto__属性值指向它的构造函数的prototype属性值。
  5. 当试图得到一个引用类型的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的prototype)中去找。

示例

// 构造函数
function Foo(name) {
this.name = name;
};

// 在构造函数的prototype上面添加一个方法
Foo.prototype.getName = function () {
return this.name;
};

// 创建实例
var f = new Foo('张三');
var name = f.getName();
console.log(name); // 输出张三
console.log(f.__proto__); // 输出一个带有getName属性的对象
console.log(Foo.prototype); // 和f.__proto__的输出一样
console.log(f.__proto__ === Foo.prototype); // 输出true,第四条规则

第五条规则就能解释f对象为什么能获取getName方法。

// 若f有getName方法呢?
f.getName = function () {
console.log('李四');
};

f.getName(); // 输出李四

如果对象本身有这个属性,就不会去原型中去找了。也就是说对象本身的属性优先级要比原型中的高。